package other.edan.erp.k3;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rkhd.platform.sdk.api.annotations.RequestMethod;
import com.rkhd.platform.sdk.api.annotations.RestApi;
import com.rkhd.platform.sdk.api.annotations.RestMapping;
import com.rkhd.platform.sdk.api.annotations.RestQueryParam;
import com.rkhd.platform.sdk.creekflow.approvalevent.ApprovalEvent;
import com.rkhd.platform.sdk.creekflow.approvalevent.ApprovalEventRequest;
import com.rkhd.platform.sdk.creekflow.approvalevent.ApprovalEventResponse;
import com.rkhd.platform.sdk.data.model.*;
import com.rkhd.platform.sdk.exception.ScriptBusinessException;
import com.rkhd.platform.sdk.log.Logger;
import com.rkhd.platform.sdk.log.LoggerFactory;
import com.rkhd.platform.sdk.service.XoqlService;
import org.apache.commons.lang.StringUtils;
import other.edan.erp.apitool.EdanK3Utils;
import other.edan.erp.utils.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 推送订单到K3
 * @Author: 黎炎松
 * @Date: 2024/11/25 11:00
 */
@RestApi(baseUrl = "/edan/order")
public class PushUpOrder implements ApprovalEvent {
    private XoqlService xoqlService = XoqlService.instance();
    private static final Logger LOGGER = LoggerFactory.getLogger();
    private static String LOGGER_MSG = "推送订单数据到K3 ==> ";

    /**
     * 审批事件
     * @param request
     * @return
     * @throws ScriptBusinessException
     */
    @Override
    public ApprovalEventResponse execute(ApprovalEventRequest request) throws ScriptBusinessException {
        LOGGER.info(LOGGER_MSG + "审批事件开始处理");
        // 推送数据
        Long orderId = request.getDataId();
        ResultVo resultVo = pushUpOrderToK3(orderId, 0);

        ApprovalEventResponse response = new ApprovalEventResponse();
        response.setMsg(resultVo.getMsg());
        response.setSuccess(resultVo.getCode() == 200 ? true : false);
        return response;
    }

    /**
     * 手动触发订单同步
     * @param
     * @return
     */
    @RestMapping(value = "/handerSync", method = RequestMethod.POST)
    public ResultVo handerSync(@RestQueryParam(name = "orderId") Long orderId) {
        LOGGER.debug("手动触发订单同步 orderId = " + orderId);
        return pushUpOrderToK3(orderId, 0);
    }


    public static void main(String[] args) {
        HCXObjectService.isLocal = true;
        PushUpOrder pushOrder = new PushUpOrder();
        //pushOrder.pushUpOrderToK3(3709230268963473L, 0);
        pushOrder.pushUpOrderToK3(3720333066672794L, 0);
    }


    /**
     * 推送、修改k3订单数据 （有k3订单编码进行编辑）
     * @param orderId
     * @param isCheckCanUp 是否检查允许变更 1: 是
     * @return
     */
    public ResultVo pushUpOrderToK3(Long orderId, int isCheckCanUp) {

        // 更新订单的推送状态
        Order upOrder = new Order();
        upOrder.setId(orderId);
        upOrder.setPushStatus__c(2);  // 推送状态 1：待同步 2：成功 3：失败
        upOrder.setPushFailReasons__c("");

        try {
            LOGGER.info(LOGGER_MSG + "处理开始");

            // 获取订单数据
            Order order = new Order();
            order.setId(orderId);
            order = HCXObjectService.get(order);

            // 如果是校验是否允许变更， 判断是否有k3销售编号
            String k3Billno = order.getK3Billno__c();
            if (isCheckCanUp == 1 && StringUtils.isBlank(k3Billno)) {
                LOGGER.error(LOGGER_MSG + "校验是否允许变更 k3销售订单编码不可为空");
                return ResultVo.error("校验是否允许变更 k3销售订单编码不可为空！");
            }

            // 推送前置判断
            String k3Code = order.getK3Code__c();
            if (StringUtils.isBlank(k3Code)) {
                LOGGER.error(LOGGER_MSG + "购货单位k3客户编码不可为空！");
                return ResultVo.error("购货单位k3客户编码不可为空！");
            }

            // 获取订单明细 单价 (不推送虚拟产品 3548916203526800)
            String sql = String.format("select id,name,FItemID__c,quantity,unitPrice,taxRate__c,unitPrice,unitPriceExcludingTax__c,priceTotal,totalAmountExcludingTax__c," +
                    "deliveryDate__c,FAdviceConsignDate__c,FNote__c,FEntrySelfS0173__c,FEntrySelfS0174__c,correspondingCode__c,correspondingCodes__c," +
                    "erpProductLine__c,erpProductLineActual__c " +
                    "from orderProduct where orderId = %s and productId.entityType != 3548916203526800 order by name", orderId);
            List<JSONObject> orderProduct = xoqlService.query(sql).getRecords();
            LOGGER.info(LOGGER_MSG + "orderProduct = " + orderProduct.size());

            // 获取选项
            JSONObject orderDesc = ComUtils.getEntityDesc("order");
            Map<String, String> settleOpt = ComUtils.getMapsFromDescribeJson(orderDesc, "FSettleId__c", "value", "apiKey"); // 结算方式
            Map<String, String> deliveryOpt = ComUtils.getMapsFromDescribeJson(orderDesc, "FHeadSelfS0150__c", "value", "apiKey"); // 发货方式
            Map<String, String> salesOpt = ComUtils.getMapsFromDescribeJson(orderDesc, "FHeadSelfS0170__c", "value", "apiKey"); // 销售类型
            Map<String, String> payOpt = ComUtils.getMapsFromDescribeJson(orderDesc, "FPayStyle__c", "value", "apiKey"); // 付款方式
            Map<String, String> ticketOpt = ComUtils.getMapsFromDescribeJson(orderDesc, "FHeadSelfS0176__c", "value", "apiKey"); // 票种

            // 通用选项集
            JSONArray salesAreaOpt = ComUtils.getGlobalPicks("globalPick62__c"); // 销售区域
            JSONArray productLineOpt = ComUtils.getGlobalPicks("globalPick53__c"); // 产品产品线

            // 获取员工工号
            Set<Long> userSet = new HashSet<>();
            if (order.getFEmpID__c() != null) userSet.add(order.getFEmpID__c()); // 业务员
            if (order.getFHeadSelfS0182__c() != null) userSet.add(order.getFHeadSelfS0182__c()); // 业务员2
            if (order.getPrepareDocument__c() != null) userSet.add(order.getPrepareDocument__c()); // 制单人
            if (order.getSupervisor__c() != null) userSet.add(order.getSupervisor__c()); // 主管
            if (order.getFHeadSelfS0187__c() != null) userSet.add(order.getFHeadSelfS0187__c()); // 跟单员
            sql = String.format("select id,name,employeeCode from user where id in (%s)", StringUtils.join(userSet, ","));
            Map<Long, String> crmUserMap = xoqlService.query(sql).getRecords().stream().collect(Collectors.toMap(e -> e.getLong("id"), e1 -> e1.getString("employeeCode"), (e, e1) -> e));

            // 拼接发送数据
            JSONObject sendData = new JSONObject();
            sendData.put("orderId", order.getId().toString());
            sendData.put("orderNo", order.getPo());
            sendData.put("fdate", DateTools.longToString(order.getCreatedAt(), DateTools.FORMATTIME)); // 日期
            sendData.put("fplanCategory", "STD"); // 计划类别
            sendData.put("fcustid", k3Code); // 购货单位
            sendData.put("fsettleID", settleOpt.get(order.getFSettleId__c() + "")); // 结算方式
            sendData.put("fheadSelfS0150", deliveryOpt.get(order.getFHeadSelfS0150__c() + "")); // 发货方式
            sendData.put("fheadSelfS0157", order.getContactAddress()); // 收货地点
            sendData.put("fheadSelfS0156", order.getReceiverName()); // 收货人
            sendData.put("fheadSelfS0152", order.getReceiverTel()); // 收货人联系电话
            sendData.put("fheadSelfS0170", salesOpt.get(order.getFHeadSelfS0170__c() + "")); // 销售类型
            sendData.put("fheadSelfS01106", payOpt.get(order.getFPayStyle__c() + "")); // 付款方式
            sendData.put("fcurrencyID", "RMB"); // 币别
            sendData.put("fheadSelfS0172", DateTools.longToString(order.getFHeadSelfS0172__c() , DateTools.FORMATTIME)); // 合同签订日期
            sendData.put("fheadSelfS0153", order.getFHeadSelfS0153__c()); // 正式合同编号
            sendData.put("fheadSelfS0176", ticketOpt.get(order.getFHeadSelfS0176__c() + "")); // 票种（FID)
            sendData.put("fheadSelfS0149", ComUtils.getOptionApiKey(salesAreaOpt, order.getSalesTerritory__c())); // 销售区域
            sendData.put("fheadSelfS0174", DateTools.longToString(order.getFHeadSelfS0174__c(), DateTools.FORMATTIME)); // 回款日期
            sendData.put("fheadSelfS0177", order.getFHeadSelfS0177__c()); // 回款金额
            sendData.put("fheadSelfS0199", order.getFHeadSelfS0199__c()); // 回款总金额
            sendData.put("fexplanation", order.getFExplanation__c()); // 摘要
            sendData.put("fheadSelfS0190", order.getRegionCode__c()); // 大洲代码
            sendData.put("fheadSelfS0191", order.getRegion__c()); // 大洲
            sendData.put("fheadSelfS0192", order.getArea__c()); // 区域
            sendData.put("fheadSelfS0193", order.getAreaCode__c()); // 区域代码
            sendData.put("fheadSelfS0161", order.getFHeadSelfS0161__c()); // 配件包装信息备注
            sendData.put("salesman", crmUserMap.get(order.getFEmpID__c())); // 业务员（员工工号）
            sendData.put("manager", crmUserMap.get(order.getSupervisor__c())); // 主管（员工工号）
            sendData.put("follower", crmUserMap.get(order.getFHeadSelfS0187__c())); // 跟单员（员工工号）

            // 部门
            Long departmentId = order.getDepartment__c();
            if (departmentId != null) {
                Department department = new Department();
                department.setId(departmentId);
                department = HCXObjectService.get(department);

                // 获取部门名称
                String departName = department.getDepartName();
                Integer poct = order.getPoct__c();
                if (Objects.equals(poct, 1)) {
                    departName += "-POCT";
                }
                sendData.put("department", departName); // 部门名称
            }

            sendData.put("salesman2", crmUserMap.get(order.getFHeadSelfS0182__c())); // 业务员2（员工工号）
            sendData.put("biller", crmUserMap.get(order.getPrepareDocument__c())); // 制单人（员工工号）

            // 是否援外（是/否）
            Integer fHeadSelfS0195 = order.getFHeadSelfS0195__c();
            if (fHeadSelfS0195 != null) {
                sendData.put("fheadSelfS0195", fHeadSelfS0195 == 1 ? "是" : "否");
            }

            // 援外国家
            Long aidCountry = order.getAidCountry__c();
            if (aidCountry != null) {
                CustomerCountry__c customerCountry = new CustomerCountry__c();
                customerCountry.setId(aidCountry);
                customerCountry = HCXObjectService.get(customerCountry);
                sendData.put("fheadSelfS0197", customerCountry.getFName__c());
            }

            //sendData.put("fexchangeRateType", ""); // 汇率类型 --
            //sendData.put("fexchangeRate", ""); // 汇率
            //sendData.put("fheadSelfS0171", ""); // 合同付款期
            //sendData.put("fheadSelfS0178", ""); // 开票日期 --
            //sendData.put("fheadSelfS0169", ""); // 是否开票(是/否) --
            //sendData.put("fheadSelfS0167", ""); // 发票邮寄时间
            //sendData.put("fheadSelfS0181", ""); // 发票邮寄编号
            //sendData.put("fheadSelfS0168", ""); // 财务发票号码
            //sendData.put("fheadSelfS0154", ""); // A OR B（A/B）
            //sendData.put("fheadSelfS0155", ""); // 销售国家
            //sendData.put("fheadSelfS0189", ""); // 最终销售国家
            //sendData.put("fsaleStyle", ""); // 销售方式（FID）
            //sendData.put("fheadSelfS01103", ""); // 国内承运商（FID）
            //sendData.put("fheadSelfS0173", ""); // 发货日期
            //sendData.put("fheadSelfS0180", ""); // 合同返回
            //sendData.put("FHeadSelfS0198", ""); // 合同接收日期
            //sendData.put("fheadSelfS0179", ""); // 是否产生序号

            // 订单明细
            JSONArray orderDetailList = new JSONArray();
            for (JSONObject detail : orderProduct) {
                JSONObject orderDetail = new JSONObject();
                orderDetail.put("fentryselfs01103", detail.getString("id")); // 订单明细id
                orderDetail.put("fentryid", detail.getString("name")); // 序号
                orderDetail.put("fnumber", detail.getString("FItemID__c")); // 产品编码
                orderDetail.put("fqty", detail.getString("quantity")); // 数量
                orderDetail.put("fauxprice", detail.getString("unitPriceExcludingTax__c")); // 单价(不含税)
                orderDetail.put("fauxtaxprice", detail.getString("unitPrice")); // 含税单价
                orderDetail.put("famount", detail.getString("totalAmountExcludingTax__c")); // 金额（不含税）
                orderDetail.put("fallstdamount", detail.getString("priceTotal")); // 含税金额
                orderDetail.put("fcess", detail.getString("taxRate__c")); // 税率
                orderDetail.put("fdate", DateTools.longToString(detail.getLong("deliveryDate__c"), DateTools.FORMATTIME)); // 交货日期
                orderDetail.put("fadviceconsigndate", DateTools.longToString(detail.getLong("FAdviceConsignDate__c"), DateTools.FORMATTIME)); // 建议交货日期
                orderDetail.put("fnote", detail.getString("FNote__c")); // 备注
                orderDetail.put("fentryselfs0173", detail.getDouble("FEntrySelfS0173__c")); // 主机保修期
                orderDetail.put("fentryselfs0174", detail.getDouble("FEntrySelfS0174__c")); // 配件保修期
                orderDetail.put("fentryselfs0183", detail.getString("correspondingCodes__c")); // 发票库对应物料代码
                orderDetail.put("fentryselfs0161", getOptionStr(detail.getJSONArray("erpProductLine__c"))); // 产品线
                orderDetail.put("fentryselfs0182", ComUtils.getOptionApiKey(productLineOpt, getOptionStr(detail.getJSONArray("erpProductLineActual__c")))); // 产品线（实际）
                orderDetailList.add(orderDetail);
            }
            sendData.put("seorderentryList", orderDetailList);

            // 判断是新增还是修改
            String optStr = "新增";
            String reqUrl = EdanK3Utils.INSERT_ORDER;
            if (isCheckCanUp == 1) {
                optStr = "校验是否允许变更";
                reqUrl = EdanK3Utils.IS_CAN_UPORDER;
                sendData.put("fbillNo", k3Billno);
            } else {
                if (StringUtils.isNotBlank(k3Billno)) {
                    optStr = "更新";
                    reqUrl = EdanK3Utils.UPDATE_ORDER;
                    sendData.put("fbillNo", k3Billno);
                }
            }
            LOGGER.info(LOGGER_MSG + "sendData = " + sendData);


            LOGGER.info(LOGGER_MSG + "推送订单执行操作 = " + optStr);
            ResultBody resultBody = EdanK3Utils.sendPost(sendData, reqUrl, "");
            if (!Objects.equals(resultBody.getCode(), "200")) {

                upOrder.setPushStatus__c(3);  // 推送状态 1：待同步 2：成功 3：失败
                upOrder.setPushFailReasons__c(resultBody.getMessage());
                if (isCheckCanUp != 1) HCXObjectService.update(upOrder);

                LOGGER.error(LOGGER_MSG + "推送订单异常: " + resultBody.getMessage());
                return ResultVo.error("推送订单异常:" + resultBody.getMessage());
            }

            // 保存订单编号
            Object result = resultBody.getResult();
            if (result != null) {
                JSONObject obj = JSONObject.parseObject(result.toString());
                String billno = obj.getString("billno");
                upOrder.setK3Billno__c(billno != null ? billno.trim() : "");
                upOrder.setFHeadSelfS0175__c(obj.getString("serial")); // 序号
            }
            LOGGER.info(LOGGER_MSG + "upOrder: " + upOrder);
            if (isCheckCanUp != 1) HCXObjectService.update(upOrder);

            LOGGER.info(LOGGER_MSG + optStr);
            return ResultVo.success(optStr + "成功", null);
        } catch (Exception e) {
            e.printStackTrace();

            upOrder.setK3Billno__c("");
            upOrder.setFHeadSelfS0175__c("");
            upOrder.setPushStatus__c(3);  // 推送状态 1：待同步 2：成功 3：失败
            upOrder.setPushFailReasons__c(e.getMessage());
            if (isCheckCanUp != 1) HCXObjectService.update(upOrder);

            LOGGER.error(LOGGER_MSG + "处理异常");
            return ResultVo.error("处理异常: " + e.getMessage());
        }
    }

    public String getOptionStr(JSONArray optionArr) {
        String optStr = "";
        if (optionArr != null && optionArr.size() > 0) {
            optStr = optionArr.stream().map(v -> v.toString()).collect(Collectors.joining(","));
        }
        return optStr;
    }



}
